<?php

namespace App\Lib;

use Elasticsearch\ClientBuilder;
use stdClass;

class Search
{

    protected $esClient;

    public function __construct()
    {
        $confEs = config('es');
        $hosts = [[
            'host' => $confEs['host'],
            'port' => $confEs['port'],
            //'scheme' => 'https',
            'user' => $confEs['username'],
            'pass' => $confEs['password'],
        ]];
        $this->esClient = ClientBuilder::create()// Instantiate a new ClientBuilder
        ->setHosts($hosts)// Set the hosts
        ->build();              // Build the client object
    }


    public function indexUser($user,$index='kk_user')
    {
        if (empty($user)) {
            return false;
        }

        if ($user['user_id'] <= 16){
            return false;
        }

        $user["birthday"] = $user["birthday"]??0;

        $params = [
            'index' => $index,
            'id' => $user['user_id'],
            'body' => $user,
        ];
        try{
            $this->esClient->index($params);
        }catch (\Exception $exception){
            write_log('search', 'indexUser', $params);
            write_log('search', 'indexUser', $exception->getMessage());
        }

        return true;
    }

    //更新es
    public function updateUser($user,$index='kk_user'){
        if (empty($user)) {
            return false;
        }

        if ($user['user_id'] <= 16){
            return false;
        }

        $user["birthday"] = $user["birthday"]??0;

        $params = [
            'index' => $index,
            'id' => $user['user_id'],
            'body' => $user,
        ];
        try{
            $this->esClient->update($params);
        }catch (\Exception $exception){
            write_log('search', 'updateUser', $params);
            write_log('search', 'updateUser', $exception->getMessage());
        }

        return true;
    }

    public function delUser($userId){

        $params = [
            'index' => 'kk_user',
            'id' => $userId,
        ];
        try{
            $this->esClient->delete($params);
        }catch (\Exception $exception){
            write_log('search', 'delUser-data', $params);
            write_log('search', 'delUser', $exception->getMessage());
        }

        return true;
    }


    public function searchUser($keyWord, $page = 0, $size = 10)
    {
        $params = [
            'index' => 'kk_user',
            'size' => $size,
            'from' => $size * $page ,
            'body' => [
                'query' => [
                    'multi_match' => [
                        'query' => $keyWord,
                        'fields' => ['user_uid', 'nickname']
                    ]
                ]
            ]
        ];

        $results = $this->esClient->search($params);
        $data = $results['hits']['hits'] ?? [];
        $userArr = [];
        foreach ($data as $val){
            $userArr[]=$val['_source'];
        }
        return $userArr;
    }

    public function createIndex($params=[]){
        if(!empty($params)){
            $this->esClient->indices()->create($params);
        }else{
            $params = ['index'=>'kk_user'];
            $this->esClient->indices()->create($params);
            $params = ['index'=>'kk_room_bussiness'];
            $this->esClient->indices()->create($params);
            $params = ['index'=>'kk_room_none'];
            $this->esClient->indices()->create($params);
        }
        
    }



    public function indexRoom($room)
    {
        if (empty($room)) {
            return false;
        }
        $index = 'kk_room_none';
        if ($room['business_type'] == 1){
            $index = 'kk_room_bussiness';
        }

        $params = [
            'index' => $index,
            'id' => $room['room_id'],
            'body' => $room,
        ];
        try{
            $this->esClient->index($params);
        }catch (\Exception $exception){
            //print_r($exception->getMessage());
            write_log('search', 'indexRoom-data', $params);
            write_log('search', 'indexRoom', $exception->getMessage());
        }
        return true;
    }


    public function delRoom($roomId)
    {
        $index = 'kk_room_none';
        $params = [
            'index' => $index,
            'id' => $roomId,
        ];
        try{
            $this->esClient->delete($params);
        }catch (\Exception $exception){
            //print_r($exception->getMessage());
            write_log('search', 'indexRoom-data', $params);
            write_log('search', 'indexRoom', $exception->getMessage());
        }
        $index = 'kk_room_bussiness';
        $params = [
            'index' => $index,
            'id' => $roomId,
        ];
        try{
            $this->esClient->delete($params);
        }catch (\Exception $exception){
            //print_r($exception->getMessage());
            write_log('search', 'indexRoom-data', $params);
            write_log('search', 'indexRoom', $exception->getMessage());
        }
        return true;
    }


    public function searchRoom($keyWord, $business = 1, $page = 0, $size = 10)
    {
        $index = 'kk_room_none';
        if ($business == 1){
            $index = 'kk_room_bussiness';
        }
        $params = [
            'index' => $index,
            'size' => $size,
            'from' => $size * $page ,
            'body' => [
                'query' => [
                    'multi_match' => [
                        'query' => $keyWord,
                        // 'fields' => ['room_uid', 'name', 'notice']
                        'fields' => ['room_uid','name']
                    ]
                ]
            ]
        ];

        $results = $this->esClient->search($params);
        $data = $results['hits']['hits'] ?? [];
        $userArr = [];
        foreach ($data as $val){
            $userArr[]=$val['_source'];
        }
        return $userArr;
    }

    /**音乐搜索
     * @param $keyWord
     * @param int $page
     * @param int $size
     * @return array
     */
    public function searchMusic($keyWord, $page = 0, $size = 10)
    {
        $params = [
            'index' => 'kk_music',
            'size' => $size,
            'from' => $size * $page ,
            'body' => [
                'query' => [
                    'multi_match' => [
                        'query' => $keyWord,
                        'fields' => ['music_name','author']
                    ]
                ]
            ]
        ];

        $results = $this->esClient->search($params);
        $data = $results['hits']['hits'] ?? [];
        $userArr = [];
        foreach ($data as $val){
            $userArr[]=$val['_source'];
        }
        return $userArr;
    }

    /**添加音乐
     * @param $music
     * @return bool
     */
    public function indexProMusic($music)
    {
        if (empty($music)) {
            return false;
        }

        $params = [
            'index' => 'kk_music',
            'id' => $music['music_id'],
            'body' => $music,
        ];
        try{
            $this->esClient->index($params);
        }catch (\Exception $exception){
            //print_r($exception->getMessage());
            write_log('search', 'indexMusic-data', $params);
            write_log('search', 'indexMusic', $exception->getMessage());
        }
        return true;
    }

    /**删除音乐
     * @param $musicId
     * @return bool
     */
    public function delMusic($musicId)
    {
        $index = 'kk_music';
        $params = [
            'index' => $index,
            'id' => $musicId,
        ];
        try{
            $this->esClient->delete($params);
        }catch (\Exception $exception){
            //print_r($exception->getMessage());
            write_log('search', 'indexMusic-data', $params);
            write_log('search', 'indexMusic', $exception->getMessage());
        }
        return true;
    }

    /**
     * @param $musicId
     * @return bool
     */
    public function indexRoomHot($room)
    {
        if (empty($room)) {
            return false;
        }
        $index = 'kk_room_hot';
        $params = [
            'index' => $index,
            'id' => $room['room_id'],
            'body' => $room,
        ];
        try{
            $this->esClient->index($params);
        }catch (\Exception $exception){
            //print_r($exception->getMessage());
            write_log('search', 'indexRoomHot-data', $params);
            write_log('search', 'indexRoomHot', $exception->getMessage());
        }
        return true;
    }

    /**
     * @param string array query
     * @return bool
     */
    public function queryRoomHotIds($query)
    {
        $result = [];
        if (empty($query)) {
            return false;
        }
        $index = 'kk_room_hot';
        $params = [
            'index' => $index,
            'size' => 300,
            'body' => [
                'query' => $query,
                'sort' => [
                    'hot_sort'=> [
                        'order' => 'desc',
                    ]
                ],
            ],
            '_source'=>[
                'room_id',
                'hot_sort',
                'room_type.id',
            ],
        ];
        try{
            $result = $this->esClient->search($params);
            $result = array_column($result['hits']['hits']??[], '_source')??[];

        }catch (\Exception $exception){
            $result = [];
            // print_r($exception->getMessage());
            write_log('search', 'indexRoomHot-data', $params);
            write_log('search', 'indexRoomHot', $exception->getMessage());
        }
        return $result;
    }

    /**
     * @param string query int page, int size
     * @return bool
     */
    public function queryRoomHot($query, $page, $size)
    {
        $result = [];
        if (empty($query)) {
            return false;
        }
        $index = 'kk_room_hot';
        $params = [
            'index' => $index,
            // 'from' => $page * $size,
            'size' => $size,
            'body' => [
                'query' => $query,
                'sort' => [
                    'micro_user_count'=> [ //热度
                        'order' => 'desc',
                    ],
                    'hot_sort'=> [ //热度
                        'order' => 'desc',
                    ]
                ],
            ],
            '_source'=>[
                'room_id',
                'room_uid',
                'name',
                'image',
                'room_type',
                'room_tag',
                'tag_name',
                'create_timestamp',
                'background_pic',
                'desc',
                'level_icon',
                'room_liang_type',
                'room_liang_type',
                'union_level_icon',
                'tag_color',
                'dynamic_cover',
                'recommend_label',
                'recommend_special',
                'recommend_svag',
                'hot',
                'hot_sort',
                'pk_status',
                'online_list',
                'micro_user_count',
                'room_mode',
            ],
        ];
        try{
            $result = $this->esClient->search($params);
            $result = array_column($result['hits']['hits']??[], '_source')??[];

        }catch (\Exception $exception){
            $result = [];
//            print_r($exception->getMessage());
            write_log('search', 'indexRoomHot-data', $params);
            write_log('search', 'indexRoomHot', $exception->getMessage());
        }
        return $result;
    }

    public function delRoomHot($roomIds)
    {
        $index = 'kk_room_hot';
        $params = [
            'index' => $index,
            'body' => [
                'query' => [
                    "bool" => [
                        "must_not" => [
                            "terms" => ["_id" => $roomIds],
                        ],

                    ],
                ],
            ],
        ];
        try{
            $this->esClient->deleteByQuery($params);
        }catch (\Exception $exception){

            // print_r($exception->getMessage());
            write_log('search', 'indexRoomHot-data', $params);
            write_log('search', 'indexRoomHot', $exception->getMessage());
        }
        return true;
    }

    //查询主播随机查询
    public function searchUserIdentity($page = 0, $size = 10, $notUserIds=[])
    {
        $params = [
            'index' => 'kk_user',
            'size' => $size,
            'from' => $size * $page ,
            'body' => [
                'query' => [
                    'bool' => [
                        'must' => [
                            ['match' => ['identity_role' => 2]],
                            ['match' => ['identity_status' => 1]]
                        ]
                    ]
                ],
                'sort' =>[
                    '_script' => [
                        'script' => 'Math.random()',
                        'type'   => 'number',
                        'order'  => 'asc'
                    ]
                ]
            ]
        ];
        if(!empty($notUserIds)) {
            $params['body']['query']['bool']['must_not']['terms'] = ['user_id'=>$notUserIds];
        }

        $results = $this->esClient->search($params);
        $data = $results['hits']['hits'] ?? [];
        $userArr = [];
        foreach ($data as $val){
            $userArr[]=$val['_source'];
        }
        return $userArr;
    }

    /**
     * 检查Index 是否存在
     *
     * @return bool
     */
    public function checkIndexExists($index='')
    {
        try {
            $params = [
                'index' => $index
            ];
            return $this->esClient->indices()->exists($params);
        } catch (\Exception $e) {
            write_log('search', 'checkIndexExists操作失败', ['msg'=>$e->getMessage(),'params'=>$params]);
            return false;
        }
    }

    /**
     * 搜索公共方法
     * @return array
     */
    public function getSearchData($index,$type,$limit,$page,$query,$sort = []){
        $params = [
            'index' => $index,
            'size' => $limit,
            'from' => $limit * $page ,
            'body' => [
                'query' => $query,
            ],
            "track_total_hits"=>true,
            
        ];

        if(!empty($sort)){
            $params['body']['sort'] = [$sort];
        }

        $results = $this->esClient->search($params);

        $data = $results['hits']['hits'] ?? [];

        $allCount = $results['hits']['total']['value'] ?? 0;
        $userArr = [];
        foreach ($data as $val){
            $userArr[]=$val['_source'];
        }

        $res['total'] = $allCount;
        $res['data'] = $userArr;
        return $res;
    }
    public function getSearchData2($index,$type,$limit,$page,$query,$sort = []){
        $params = [
            'index' => $index,
            'size' => $limit,
            'from' => $limit * $page ,
            'body' => [
                'query' => $query,
            ],
            "track_total_hits"=>true,

        ];


        if(!empty($sort)){
            $params['body']['sort'] = [$sort];
        }

        $results = $this->esClient->search($params);

        $data = $results['hits']['hits'] ?? [];

        $allCount = $results['hits']['total']['value'] ?? 0;
        $userArr = [];
        foreach ($data as $val){
            $userArr[]=$val['_source'];
        }

        $res['total'] = $allCount;
        $res['data'] = $userArr;
        return $res;
    }

    //删除索引中的值
    public function delValue($index, $type, $id){
        $index = $index;
        $params = [
            'index' => $index,
            'id' => $id,
        ];
        try{
            $this->esClient->delete($params);
        }catch (\Exception $exception){
            //print_r($exception->getMessage());
            write_log('search', 'index-deldata', $params);
            write_log('search', 'deldata', $exception->getMessage());
        }
        return true;
    }

    //清空索引中的内容(保留索引)
    public function deleteAllIndex($index)
    {
        $this->esClient->deleteByQuery([
            'index' => $index,
            'body' => [
                'query' => [
                    'match_all' => new stdClass()
                ]
            ]
        ]);
    }
}